﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Abp;
using Abp.Domain.Repositories;
using Abp.Domain.Services;
using Abp.IdentityFramework;
using Abp.Localization;
using Microsoft.AspNet.Identity;
using XHD.WXZJ.Posts;

namespace XHD.WXZJ.Menus
{
  public  class MenuManager<TMenu> : IDomainService
        where TMenu:Menus
    {
        public ILocalizationManager LocalizationManager { get; set; }
        protected IRepository<TMenu> MenuRepository { get; set; }

      public MenuManager(IRepository<TMenu> menuRepository)
      {
          MenuRepository = menuRepository;
      }
        private string L(string name)
        {
            return LocalizationManager.GetString(WXZJConsts.LocalizationSourceName, name);
        }
        protected virtual async Task<IdentityResult> ValidateMenuAsync(Menus menu)
        {
            var nameValidationResult = await ValidateMenuNameAsync(menu.Name);
            return !nameValidationResult.Succeeded ? nameValidationResult : IdentityResult.Success;
        }
        protected virtual async Task<IdentityResult> ValidateMenuNameAsync(string menuName)
        {
            return !Regex.IsMatch(menuName, Menus.MenuNameRegex) ? AbpIdentityResult.Failed(L("InvalidMenuName")) : IdentityResult.Success;
        }

        public virtual IQueryable<TMenu> Menuses
        {
            get { return MenuRepository.GetAll(); }
        }

        public virtual async Task<IdentityResult> CreateAsync(TMenu menu)
        {
            if (await MenuRepository.FirstOrDefaultAsync(d => d.Name == menu.Name) != null)
            {
                return AbpIdentityResult.Failed(string.Format(L("MenuNameIsAlreadyTaken")));
            }

            var validationResult = await ValidateMenuAsync(menu);
            if (!validationResult.Succeeded)
            {
                return validationResult;
            }
            await MenuRepository.InsertAsync(menu);

            return IdentityResult.Success;
        }

        public virtual async Task<IdentityResult> UpdateAsync(TMenu menu)
        {
            if (await MenuRepository.FirstOrDefaultAsync(t => t.Name == menu.Name && t.Id != menu.Id) != null)
            {
                return AbpIdentityResult.Failed(string.Format(L("MenuNameIsAlreadyTaken"), menu.Name));
            }

            await MenuRepository.UpdateAsync(menu);
            return IdentityResult.Success;

        }

        public virtual async Task<IdentityResult> DeleteAsync(TMenu menu)
        {
            //1.先删除菜单用户表里面对应的数据
            //await PostUserRepository.DeleteByPostIdAsync(post.Id);
            //2.再删除
            await MenuRepository.DeleteAsync(menu);
            return IdentityResult.Success;
        }

        public virtual async Task<Menus> GetByIdAsync(int menuId)
        {
            var menu = await MenuRepository.FirstOrDefaultAsync(menuId);
            if (menu == null)
            {
                throw new AbpException(string.Format("不存在菜单id为{0}的菜单", menuId));
            }
            return menu;
        }

        public virtual async Task<Menus> FindByIdAsync(int menuId)
        {
            return await MenuRepository.FirstOrDefaultAsync(menuId);
        }
        /// <summary>
        /// 根据菜单名称查找菜单对象
        /// </summary>
        /// <param name="postName">菜单名称</param>
        /// <returns></returns>
        public virtual async Task<Menus> FindByNameAsync(string menuName)
        {
            return await MenuRepository.FirstOrDefaultAsync(
                menu => menu.Name == menuName
                );
        }

        /// <summary>
        /// 根据显示名称查找菜单对象
        /// </summary>
        /// <param name="displayName">显示名称</param>
        /// <returns></returns>
        public virtual async Task<Menus> FindByDisplayNameAsync(string displayName)
        {
            return await MenuRepository.FirstOrDefaultAsync(
                menu => menu.DisplayName == displayName
                );
        }
    }
}
